<template>
  <div>
    <div class="h-screen">
      <wallwindow :showPosterVideo="showPosterVideo"></wallwindow>
      <!-- <el-image style="animation: header-effect 2s"
                class="background-image"
                :src="$constant.random_image"
                fit="cover">
        <div slot="error" class="image-slot background-image-error"></div>
      </el-image> -->
      <!-- 输入框 -->
      <div class="message-in" style="text-align: center">
        <h2 class="message-title">树洞</h2>
        <div>
          <input class="message-input"
                 type="text"
                 style="outline: none;width: 70%"
                 placeholder="留下点什么啦~"
                 v-model="messageContent"
                 @click="show = true"
                 maxlength="60"/>
          <button v-show="show"
                  style="margin-left: 12px;cursor: pointer;width: 20%"
                  @click="submitMessage"
                  class="message-input">发射
          </button>
        </div>
      </div>
      <!-- 弹幕 -->
      <div ref="barrageContainer" class="barrage-container">
        <div v-for="barrage in visibleBarrages" 
             :key="barrage.id"
             :style="getBarrageStyle(barrage)"
             class="barrage-item">
          <div v-if="barrage.avatar" class="barrage-avatar">
            <img :src="barrage.avatar" class="barrage-avatar-img" alt="">
          </div>
          <div class="barrage-content">
            {{ barrage.content }}
          </div>
        </div>
      </div>
    </div>
    <div class="comment-wrap">
      <div class="comment-content">
        <comment :source="$constant.source" :userId="$constant.userId"></comment>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, computed, inject, nextTick } from 'vue';
import { useMainStore } from '../store/index';
import comment from "./comment/comment.vue";
import wallwindow from "./common/wallwindow.vue";
import { listTreeHole, saveTreeHole } from '../api/tree-hole';

// 全局属性
const $common = inject('$common');
const $message = inject('$message');
const $constant = inject('$constant');

const store = useMainStore();
const show = ref(false);
const messageContent = ref("");
const barrageList = ref([]);
const visibleBarrages = ref([]);
const barrageContainer = ref(null);
const showPosterVideo = ref(true);
const containerHeight = ref(0);
const containerWidth = ref(0);
const rowCount = ref(10); // 将容器分成多少行
const rowHeight = ref(0); // 每行高度
const animationFrame = ref(null);
const rowEndPositions = ref({}); // 跟踪每行最后一个弹幕的结束位置

// 基础弹幕速度（像素/秒）
const baseSpeed = 100;
// 弹幕持续时间（秒）
const barrageDuration = 15;

onMounted(() => {
  getTreeHole();
  initBarrageContainer();
  window.addEventListener('resize', handleResize);
  startBarrageAnimation();
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize);
  if (animationFrame.value) {
    cancelAnimationFrame(animationFrame.value);
  }
});

// 处理窗口大小变化
const handleResize = () => {
  if (animationFrame.value) {
    cancelAnimationFrame(animationFrame.value);
  }
  
  // 清空当前弹幕，重新初始化
  visibleBarrages.value = [];
  rowEndPositions.value = {};
  
  nextTick(() => {
    initBarrageContainer();
    startBarrageAnimation();
  });
};

const initBarrageContainer = () => {
  if (barrageContainer.value) {
    containerHeight.value = barrageContainer.value.clientHeight;
    containerWidth.value = barrageContainer.value.clientWidth;
    
    // 计算每行高度
    rowHeight.value = Math.floor(containerHeight.value / rowCount.value);
    
    // 初始化行结束位置
    for (let i = 0; i < rowCount.value; i++) {
      rowEndPositions.value[i] = 0;
    }
  }
};

// 获取弹幕样式
const getBarrageStyle = (barrage) => {
  return {
    position: 'absolute',
    top: `${barrage.top}px`,
    right: `-${barrage.width}px`,
    transform: `translateX(-${barrage.position}px)`,
    transition: `transform ${barrageDuration}s linear`,
    display: 'flex',
    alignItems: 'center',
    whiteSpace: 'nowrap',
    willChange: 'transform', // 优化GPU加速
    zIndex: barrage.zIndex || 1
  };
};

// 计算弹幕宽度（估算）
const estimateBarrageWidth = (content, hasAvatar) => {
  // 每个中文字符约20px，英文字符约10px，加上padding和头像
  const baseWidth = 20; // 基础宽度（padding等）
  const avatarWidth = hasAvatar ? 35 : 0; // 头像宽度+间距
  const contentWidth = content.split('').reduce((acc, char) => {
    // 粗略估计：中文字符宽度是英文的2倍
    const charWidth = /[\u4e00-\u9fa5]/.test(char) ? 20 : 10;
    return acc + charWidth;
  }, 0);
  
  return baseWidth + avatarWidth + contentWidth;
};

// 获取可用的行
const getAvailableRow = (barrageWidth) => {
  const now = Date.now();
  const availableRows = [];
  
  // 检查每一行是否有足够的空间放置新弹幕
  for (let i = 0; i < rowCount.value; i++) {
    // 如果该行结束位置为0，或者最后一个弹幕已经前进足够距离
    if (rowEndPositions.value[i] <= 0 || rowEndPositions.value[i] + barrageWidth < containerWidth.value) {
      availableRows.push(i);
    }
  }
  
  if (availableRows.length > 0) {
    // 随机选择一个可用行
    const randomIndex = Math.floor(Math.random() * availableRows.length);
    return availableRows[randomIndex];
  }
  
  // 如果所有行都满了，找出最快空出来的一行
  let minEndPosition = Infinity;
  let selectedRow = 0;
  
  for (let i = 0; i < rowCount.value; i++) {
    if (rowEndPositions.value[i] < minEndPosition) {
      minEndPosition = rowEndPositions.value[i];
      selectedRow = i;
    }
  }
  
  return selectedRow;
};

const startBarrageAnimation = () => {
  let lastTime = performance.now();
  let accumulatedTime = 0;
  const interval = 1000; // 每秒尝试添加新弹幕的间隔（毫秒）
  
  const animate = (currentTime) => {
    const deltaTime = currentTime - lastTime;
    lastTime = currentTime;
    
    // 累积时间，用于控制添加新弹幕的频率
    accumulatedTime += deltaTime;
    
    // 每隔一定时间尝试添加新弹幕
    if (accumulatedTime > interval && barrageList.value.length > 0) {
      accumulatedTime = 0;
      
      // 从弹幕列表中随机选择一条
      const index = Math.floor(Math.random() * barrageList.value.length);
      const item = barrageList.value[index];
      
      if (item) {
        // 估算弹幕宽度
        const hasAvatar = !$common.isEmpty(item.avatar);
        const width = estimateBarrageWidth(item.content, hasAvatar);
        
        // 获取可用行
        const rowIndex = getAvailableRow(width);
        
        // 计算弹幕垂直位置
        const top = rowIndex * rowHeight.value + (rowHeight.value - 30) / 2; // 30是弹幕高度估计值
        
        // 创建新弹幕
        const newBarrage = {
          ...item,
          rowIndex,
          top,
          position: 0,
          width,
          startTime: currentTime,
          zIndex: Math.floor(Math.random() * 10) + 1 // 随机层级，避免视觉上的规则性
        };
        
        // 更新该行的结束位置
        rowEndPositions.value[rowIndex] = width;
        
        // 添加到可见弹幕列表
        visibleBarrages.value.push(newBarrage);
        
        // 启动弹幕动画
        nextTick(() => {
          setTimeout(() => {
            if (newBarrage && visibleBarrages.value.includes(newBarrage)) {
              newBarrage.position = containerWidth.value + width;
            }
          }, 50); // 小延迟确保DOM更新
        });
        
        // 设置弹幕结束后的清理
        setTimeout(() => {
          // 移除弹幕
          visibleBarrages.value = visibleBarrages.value.filter(b => b.id !== newBarrage.id);
          
          // 重置该行的结束位置
          if (rowEndPositions.value[rowIndex] === width) {
            rowEndPositions.value[rowIndex] = 0;
          }
        }, barrageDuration * 1000 + 100); // 比动画时间稍长一点
      }
    }
    
    // 继续下一帧动画
    animationFrame.value = requestAnimationFrame(animate);
  };
  
  animationFrame.value = requestAnimationFrame(animate);
};

const getTreeHole = () => {
  listTreeHole()
    .then((res) => {
      if (!$common.isEmpty(res.data)) {
        barrageList.value = res.data.map(m => ({
          id: m.id,
          avatar: m.avatar,
          content: m.message
        }));
      }
    })
    .catch((error) => {
      $message({
        message: error.message,
        type: "error"
      });
    });
};

const submitMessage = () => {
  if (messageContent.value.trim() === "") {
    $message({
      message: "你还没写呢~",
      type: "warning",
    });
    return;
  }

  let treeHole = {
    message: messageContent.value.trim()
  };

  if (!$common.isEmpty(store.currentUser) && !$common.isEmpty(store.currentUser.avatar)) {
    treeHole.avatar = store.currentUser.avatar;
  }

  saveTreeHole(treeHole)
    .then((res) => {
      if (!$common.isEmpty(res.data)) {
        const newDanmu = {
          id: res.data.id,
          avatar: res.data.avatar,
          content: res.data.message
        };
        barrageList.value.push(newDanmu);
      }
    })
    .catch((error) => {
      $message({
        message: error.message,
        type: "error"
      });
    });

  messageContent.value = "";
  show.value = false;
};
</script>

<style scoped>
  .message-in {
    text-shadow: 2px 2px 3px #ff000088;
    transition: .5s;
    position: absolute;
    left: 50%;
    top: 40%;
    transform: translate(-50%, -50%);
    color: var(--white);
    animation: hideToShow 2.5s;
    width: 360px;
    z-index: 10;
  }

  .message-title {
    user-select: none;
    text-align: center;
  }
  .message-input:hover,.message-input:focus{
    color: var(--themeBackground);
    border: var(--themeBackground) 1px solid;
  }
  .message-input {
    font-family: var(--globalFont);
    transition: .5s;
    border-radius: 1.2rem;
    border: var(--white) 1px solid;
    color: var(--white);
    background: var(--transparent);
    padding: 10px 10px;
  }

  .message-input::-webkit-input-placeholder {
    color: var(--white);
  }

  .barrage-container {
    position: absolute;
    top: 50px;
    left: 0;
    right: 0;
    bottom: 0;
    height: calc(100% - 50px);
    width: 100%;
    user-select: none;
    overflow: hidden;
  }

  .barrage-item {
    position: absolute;
    display: flex;
    align-items: center;
    white-space: nowrap;
    pointer-events: none;
  }

  .barrage-avatar {
    width: 30px;
    height: 30px;
    margin-right: 5px;
  }

  .barrage-avatar-img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
  }

  .barrage-content {
    padding: 5px 10px;
    background-color: rgba(0, 0, 0, 0.5);
    border-radius: 15px;
    color: white;
  }

  .comment-wrap {
    background: var(--background);
    width: 100%;
  }

  .comment-content {
    max-width: 800px;
    margin: 0 auto;
    padding: 40px 20px;
  }

  /* 弹幕动画 */
  .barrage-enter-active {
    transition: all 0.3s ease;
  }
  .barrage-leave-active {
    transition: all 0.8s ease;
  }
  .barrage-enter-from {
    opacity: 0;
    transform: translateX(100px);
  }
  .barrage-leave-to {
    opacity: 0;
    transform: translateX(-100px);
  }
</style>

